package junior.db.dao.base;

import junior.db.dao.query.AbstractQuery;

import java.util.ArrayList;
import java.util.List;

/**
 * union查询的辅助类
 */
public class UnionQuery {
    protected String namespace;
    private final List<UnionQueryParamItem> items = new ArrayList<>();
    private List<Sort> sorts;
    private Limit limit;
    
    public UnionQuery(String namespace) {
        this.namespace = namespace;
    }
    
    public void add(String union, AbstractQuery param) {
        items.add(new UnionQueryParamItem(union, param));
    }
    
    public List<UnionQueryParamItem> getItems() {
        return items;
    }
    
    public List<Sort> getSorts() {
        return sorts;
    }
    
    public UnionQuery asc(String field) {
        prepareSorts();
        sorts.add(Sort.asc(field));
        return this;
    }
    
    public UnionQuery desc(String field) {
        prepareSorts();
        sorts.add(Sort.desc(field));
        return this;
    }
    
    public Limit getLimit() {
        return limit;
    }
    public UnionQuery limit(int limit) {
        this.limit = new Limit(limit);
        return this;
    }
    public UnionQuery limit(int start, int limit) {
        this.limit = new Limit(start, limit);
        return this;
    }
    
    private void prepareSorts() {
        if(sorts == null) {
            sorts = new ArrayList<Sort>(2);
        }
    }
    
    public String getOrderBy() {
        if (sorts != null && !sorts.isEmpty()) {
            StringBuilder buff = new StringBuilder();
            int index = 0;
            for (Sort sort : sorts) {
                if (sort.getField() == null) continue;
                
                String field = sort.getField();
                
                if (index++ > 0) {
                    buff.append(", ");
                }
                if (sort.isCompression()) {
                    buff.append(MybatisHelper.getCustomSql(namespace, field, null, p -> null));
                } else {
                    buff.append(MybatisHelper.field2Column(namespace, field, null, p -> null));
                }
                if (!sort.isAsc()) {
                    buff.append(" desc");
                }
            }
            return buff.toString();
        }
        return null;
    }
    
    public static class UnionQueryParamItem {
        private final String union;
        private final AbstractQuery param;
        UnionQueryParamItem(String union, AbstractQuery param) {
            this.union = union;
            this.param = param;
        }
        public String getUnion() {
            return union;
        }
        public AbstractQuery getParam() {
            return param;
        }
    }
}
